package com.aizhaiyu.blue_record

import android.bluetooth.*
import android.bluetooth.le.*
import android.content.Context
import android.os.ParcelUuid
import android.util.Log
import java.util.*

class BlePeripheralService(
    private val context: Context,
    private val onCommandReceived: (String) -> Unit
) {
    private var bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    private var bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
    private var bluetoothLeAdvertiser: BluetoothLeAdvertiser? = null
    private var gattServer: BluetoothGattServer? = null
    private var connectedDevices = mutableSetOf<BluetoothDevice>()
    
    companion object {
        private const val TAG = "BlePeripheralService"
        private val SERVICE_UUID = UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb")
        private val CONTROL_CHARACTERISTIC_UUID = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb")
        private val NOTIFY_CHARACTERISTIC_UUID = UUID.fromString("0000ffe2-0000-1000-8000-00805f9b34fb")
    }

    private val advertiseCallback = object : AdvertiseCallback() {
        override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
            Log.i(TAG, "BLE广播开启成功")
        }

        override fun onStartFailure(errorCode: Int) {
            val errorMessage = when(errorCode) {
                ADVERTISE_FAILED_ALREADY_STARTED -> "广播已经开启"
                ADVERTISE_FAILED_DATA_TOO_LARGE -> "广播数据太大"
                ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> "设备不支持广播"
                ADVERTISE_FAILED_INTERNAL_ERROR -> "内部错误"
                ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> "广播数量超限"
                else -> "未知错误: $errorCode"
            }
            Log.e(TAG, "BLE广播开启失败: $errorMessage")
        }
    }

    private val gattServerCallback = object : BluetoothGattServerCallback() {
        override fun onConnectionStateChange(device: BluetoothDevice, status: Int, newState: Int) {
            try {
                when (newState) {
                    BluetoothProfile.STATE_CONNECTED -> {
                        Log.i(TAG, "设备连接: ${device.address}")
                        connectedDevices.add(device)
                    }
                    BluetoothProfile.STATE_DISCONNECTED -> {
                        Log.i(TAG, "设备断开: ${device.address}")
                        connectedDevices.remove(device)
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "处理连接状态改变时出错", e)
            }
        }

        override fun onCharacteristicWriteRequest(
            device: BluetoothDevice,
            requestId: Int,
            characteristic: BluetoothGattCharacteristic,
            preparedWrite: Boolean,
            responseNeeded: Boolean,
            offset: Int,
            value: ByteArray
        ) {
            try {
                val command = String(value)
                Log.i(TAG, "收到写入请求: $command")
                
                // 发送命令到 Flutter 层
                onCommandReceived(command)
                
                if (responseNeeded) {
                    gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null)
                }
            } catch (e: Exception) {
                Log.e(TAG, "处理写入请求时出错", e)
                if (responseNeeded) {
                    gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null)
                }
            }
        }

        override fun onCharacteristicReadRequest(
            device: BluetoothDevice,
            requestId: Int,
            offset: Int,
            characteristic: BluetoothGattCharacteristic
        ) {
            try {
                Log.i(TAG, "收到读取请求")
                gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null)
            } catch (e: Exception) {
                Log.e(TAG, "处理读取请求时出错", e)
                gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null)
            }
        }

        override fun onNotificationSent(device: BluetoothDevice, status: Int) {
            try {
                Log.i(TAG, "通知发送状态: ${if (status == BluetoothGatt.GATT_SUCCESS) "成功" else "失败"}")
            } catch (e: Exception) {
                Log.e(TAG, "处理通知发送状态时出错", e)
            }
        }

        override fun onDescriptorWriteRequest(
            device: BluetoothDevice,
            requestId: Int,
            descriptor: BluetoothGattDescriptor,
            preparedWrite: Boolean,
            responseNeeded: Boolean,
            offset: Int,
            value: ByteArray
        ) {
            try {
                Log.i(TAG, "收到描述符写入请求")
                if (responseNeeded) {
                    gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null)
                }
            } catch (e: Exception) {
                Log.e(TAG, "处理描述符写入请求时出错", e)
                if (responseNeeded) {
                    gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null)
                }
            }
        }
    }

    fun startAdvertising() {
        if (!bluetoothAdapter.isEnabled) {
            throw IllegalStateException("蓝牙未开启")
        }

        bluetoothLeAdvertiser = bluetoothAdapter.bluetoothLeAdvertiser
            ?: throw IllegalStateException("设备不支持BLE广播")

        val service = BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY)

        val controlCharacteristic = BluetoothGattCharacteristic(
            CONTROL_CHARACTERISTIC_UUID,
            BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_NOTIFY,
            BluetoothGattCharacteristic.PERMISSION_WRITE
        ).apply {
            addDescriptor(
                BluetoothGattDescriptor(
                    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),
                    BluetoothGattDescriptor.PERMISSION_WRITE or BluetoothGattDescriptor.PERMISSION_READ
                )
            )
        }

        val notifyCharacteristic = BluetoothGattCharacteristic(
            NOTIFY_CHARACTERISTIC_UUID,
            BluetoothGattCharacteristic.PROPERTY_NOTIFY,
            BluetoothGattCharacteristic.PERMISSION_READ
        ).apply {
            addDescriptor(
                BluetoothGattDescriptor(
                    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),
                    BluetoothGattDescriptor.PERMISSION_WRITE or BluetoothGattDescriptor.PERMISSION_READ
                )
            )
        }

        service.addCharacteristic(controlCharacteristic)
        service.addCharacteristic(notifyCharacteristic)

        gattServer = bluetoothManager.openGattServer(context, gattServerCallback)?.apply {
            addService(service)
        } ?: throw IllegalStateException("无法创建GATT服务器")

        val settings = AdvertiseSettings.Builder()
            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
            .setConnectable(true)
            .setTimeout(0)
            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
            .build()

        val data = AdvertiseData.Builder()
            .setIncludeDeviceName(true)
            .addServiceUuid(ParcelUuid(SERVICE_UUID))
            .build()

        bluetoothLeAdvertiser?.startAdvertising(settings, data, advertiseCallback)
            ?: throw IllegalStateException("无法启动广播")
    }

    fun stopAdvertising() {
        try {
            bluetoothLeAdvertiser?.stopAdvertising(advertiseCallback)
            connectedDevices.clear()
            gattServer?.close()
            gattServer = null
        } catch (e: Exception) {
            Log.e(TAG, "停止广播错误", e)
            throw e
        }
    }

    fun sendNotification(value: ByteArray) {
        val characteristic = gattServer?.getService(SERVICE_UUID)
            ?.getCharacteristic(NOTIFY_CHARACTERISTIC_UUID)
            ?: return

        characteristic.value = value
        connectedDevices.forEach { device ->
            gattServer?.notifyCharacteristicChanged(device, characteristic, false)
        }
    }
} 